// 最深层级
let deepLevel = 0

/**
 * 生成按钮
 * */
function createAction (actions) {
  // 查找所有的box-pointer
  const boxPointers = document.getElementsByClassName('box-pointer')
  actions.appendChild(_createElement('span', { style: 'font-size: 14px;'}, '展开到第'))

  const actionArr = []
  for (let i = 1; i < deepLevel; i ++) {
    const action = _createElement('button', { style: 'margin: 0 2px;cursor: pointer;' }, i)
    actionArr.push(action)
    action.addEventListener('click', () => {
      actionArr.forEach(o => o.className = '')
      action.className = 'action__active'
      ;[...boxPointers].forEach(boxPointer => {
        const dataLevel = Number(boxPointer.getAttribute('data-level'))
        if (dataLevel <= i) {
          // 展开
          boxPointer.textContent === '-' && boxPointer.onclick()
        } else {
          // 收起
          boxPointer.textContent === '+' && boxPointer.onclick()
        }
      })

    })
    actions.appendChild(action)
  }

  actions.appendChild(_createElement('span', { style: 'font-size: 14px;'}, '层'))
}

/**
 * 可视化函数
 *
 * @param data {string|Object|Array} 可视化的数据
 * @param fieldName {string} 父节点字段名
 * @param isLast {boolean} 是否是最后一个属性
 * @param level {number} 当前层级
 * */
function jsonParse (data, fieldName, isLast, level = 1) {
  // 设置最深层级
  deepLevel = Math.max(deepLevel, level)

  // 判空
  data = data === null || data === void 0 ? '' : data

  // 校验json字符串
  data = validateJson(data)

  // 校验url
  if (typeof data === 'string') {
    data = validateUrl(data)
  }

  // 校验对象、数组
  if (data && typeof data === 'string' && /^[{\[]/.test(data)) {
    data = validateObjStr(data)
  }

  // 不是数组或对象 就返回一个li直接展示
  if (typeof data !== 'object') {
    return _createElement('li', null,
      fieldName ? _createElement('b', null, fieldName) : '',
      fieldName ? '：' : '',
      data,
      isLast ? '' : ','
    )
  }

  // 是否是数组
  const _is_array = Array.isArray(data)

  // 创建容器
  const box = _createElement('div', { class: 'box box__open' })

  // 创建并追加 +或- 元素
  const boxPointer = _createElement('span', { class: 'box-pointer', 'data-level': level }, '+')
  // 增加点击事件
  boxPointer.onclick = () => {
    if (boxPointer.textContent === '+') {
      box.className = 'box'
      ellipsis.className = ''
      boxPointer.textContent = '-'
    } else {
      box.className = 'box box__open'
      ellipsis.className = 'ellipsis__hide'
      boxPointer.textContent = '+'
    }
  }
  box.appendChild(boxPointer)

  // 创建并追加父字段名
  if (fieldName) {
    const fieldDom = _createElement('span', null,
      _createElement('b', null, fieldName),
      ': '
    )
    box.appendChild(fieldDom)
  }

  // 创建并追加左括号
  const boxBracketLeft = _createElement('span', null,
    _is_array ? '[' : '{'
  )
  box.appendChild(boxBracketLeft)

  // 创建并追加... 展开隐藏，收起显示
  const ellipsis = _createElement('span', { class: 'ellipsis__hide' }, '...')
  box.appendChild(ellipsis)

  // 创建ul容器
  const ul = document.createElement('ul')
  box.appendChild(ul)

  if (_is_array) {
    // 是数组
    for (let i = 0, len = data.length; i < len; i ++) {
      ul.appendChild(jsonParse(data[i], '', i === len - 1, level + 1))
    }
  } else {
    // 是对象
    // 统一对象属性顺序
    const keyArr = sortObj(data)
    const len = keyArr.length
    let count = 0
    for (const key of keyArr) {
      count ++
      ul.appendChild(jsonParse(data[key], key, count === len, level + 1))
    }
  }

  // 创建并追加右括号
  const boxBracketRight = _createElement('span', null,
    _is_array ? ']' : '}',
    isLast ? '' : ','
  )
  box.appendChild(boxBracketRight)

  return box
}

// 初始化拖拽事件
initDrag(document.getElementById('divider'))

// 输入事件
document.getElementById('textarea').addEventListener('input', (e) => {
  const val = e.target.value
  const root = document.getElementById('root')
  const actions = document.getElementById('actions')
  root.innerHTML = ''
  actions.innerHTML = ''
  deepLevel = 0
  if (val) {
    root.appendChild(jsonParse(val))
    createAction(actions)
  }
})